package com.jeasy.aspect;

import javax.servlet.http.HttpServletRequest;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;

import com.jeasy.AnnotationValidable;
import com.jeasy.Validator;
import com.jeasy.resolver.JsonObj;

import lombok.extern.slf4j.Slf4j;

/**
 * Controller请求方法入参校验Aspect
 * @author taomk
 * @version 1.0
 * @since 15-5-22 下午7:57
 */
@Slf4j
@Aspect
public class MethodArgumentValidateAspect {

	@Autowired
	private Validator validator;

	/**
	 * Pointcut
	 * 定义Pointcut，Pointcut的名称为aspectjMethod()，此方法没有返回值和参数
	 * 该方法就是一个标识，不进行调用
	 */
	@Pointcut("execution(public * com.jeasy.*.controller.*Controller.*(..))")
	private void aspectjMethod(){}

	@Around(value = "aspectjMethod()")
	public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
		// 获取目标对象
		Object target = pjp.getTarget();
		// 获取目标对象对应的类名
		String className = target.getClass().getName();
		// 获取目标对象正在执行的方法
		Signature signature = pjp.getSignature();
		// 获取目标对象上正在执行的方法名
		String methodName = signature.getName();
		// 获取目标对象上正在执行的Methods
		Method [] methods = signature.getDeclaringType().getMethods();
		Method targetMethod = methods[0];
		// 获取目标对象上正在执行的方法名参数
		Object [] args = pjp.getArgs();

		// 获取目标对象上的属性
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

		Annotation [][] parameterAnnotations = targetMethod.getParameterAnnotations();

		for (int i = 0; i < parameterAnnotations.length; i++) {
			for (int j = 0; j < parameterAnnotations[i].length; j++) {
				if (JsonObj.class.isInstance(parameterAnnotations[i][j])) {
					if (args[i] instanceof AnnotationValidable) {
						validator.validate((AnnotationValidable)args[i]);
					}
				}
			}
		}

		return pjp.proceed();
	}

	public ModelAndView auth(ProceedingJoinPoint joinPoint) {


		if (true) {
			try {
				return (ModelAndView)joinPoint.proceed();
			}
			catch(Throwable theEnd) {
				ModelAndView mav = new ModelAndView("json/error");
				mav.getModel().put("error", theEnd.getMessage());
				return mav;
			}
		}
		else {
			ModelAndView mav = new ModelAndView("json/error");
			mav.getModel().put("error", "unauthorised");
			return mav;
		}
	}
}
